package com.sbm.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TestAOP {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestAOP.class);

    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void controllerPointcut() {
    }

    @Before("controllerPointcut()")
    public void before(JoinPoint point) {
        LOGGER.info("Pointcut Before");
    }

    @After("controllerPointcut()")
    public void after(JoinPoint point) {
        LOGGER.info("Pointcut After");
    }

    @AfterReturning(pointcut = "controllerPointcut()", returning = "returnValue")
    public void afterReturn(JoinPoint point, Object returnValue) {
        LOGGER.info("Pointcut AfterReturning");
    }

    @AfterThrowing(pointcut = "controllerPointcut()", throwing = "ex")
    public void afterThrowable(Throwable ex) {
        LOGGER.info("Pointcut AfterThrowing");
    }

    @Around("controllerPointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        LOGGER.info("Pointcut Around Before");
        Object result = point.proceed();
        LOGGER.info("Pointcut Around After");
        return result;
    }
}
